home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mac-Source 1994 July
/
Mac-Source_July_1994.iso
/
C and C++
/
Science⁄Math
/
Scientist's Helper src
/
s.helper.3
/
reggauss.c
< prev
next >
Wrap
C/C++ Source or Header
|
1985-11-30
|
11KB
|
384 lines
#include "all.h"
#include "regtabext.h"
multifit()
{
int indList[32], nInd, i, j, k, n, inWord, yCol, zCol, anyNaN, nstore, ierror, counts, flag;
char c, str[80];
float t, x[33], y, z, vec[33], *a;
if( (strcmp(command.cmdWord[1],"type")!=0) &&
(strcmp(command.cmdWord[1],"keep")!=0) &&
(strcmp(command.cmdWord[1],"remove")!=0) &&
(strcmp(command.cmdWord[1],"compute")!=0) ) {
ErrMsg(badModifier);
}
/*decode independent column list*/
n = strlen( command.cmdWord[2] );
command.cmdWord[2][n]=' ';
command.cmdWord[2][n+1]='\0';
n++;
nInd = 0;
inWord = FALSE;
for( i=0; i<n; i++ ) {
c = command.cmdWord[2][i];
if( (c=='\t') || (c==',') ) c=' ';
if( (!inWord) && (c!=' ') ) {
inWord=TRUE;
nInd++;
if( nInd>32 ) ErrMsg("too many independent columns");
j=0;
str[0]=c;
}
else if( inWord && (c==' ') ) {
j++;
str[j]='\0';
SToI( str, &(indList[nInd]) );
if( GoodCol(indList[nInd])!=0 ) ErrMsg("bad independent column");
inWord=FALSE;
}
else if( inWord && (c!=' ') ) {
j++;
str[j]=c;
} /*end if*/
} /*end for i*/
if (nInd<1) ErrMsg("too few independent columns");
SToI( command.cmdWord[3], &yCol );
if( GoodCol(yCol)!=0 ) ErrMsg("bad dependent column");
/*allocate matrix and zero it*/
nstore = nInd+1;
a = NewPtr( 4L * (long)(nstore*nstore) );
if( MemError()!=noErr ) ErrMsg("not enough memory");
for( i=0; i<nstore; i++ ) {
vec[i]=0.0;
for( j=0; j<nstore; j++ ) {
*(a+i*nstore+j)=0.0;
} /*end for j*/
} /*end for i*/
counts = 0;
for( i=1; i<=table.header.rows; i++ ) {
x[0]=1.0;
anyNaN = FALSE;
for( j=1; j<=nInd; j++ ) {
GetTable( i, indList[j], &(x[j]) );
if( NaN(&x[j]) ) {
anyNaN = TRUE;
break;
} /*end if*/
} /*end for j*/
GetTable( i, yCol, &y );
if( anyNaN || NaN(&y) ) break;
counts++;
for( j=0; j<nstore; j++ ) {
vec[j] += y*x[j];
for( k=0; k<nstore; k++ ) {
*(a+j*nstore+k) += x[j]*x[k];
} /*end for k*/
} /*end for j*/
} /*end for i*/
gauss(a,vec,nstore,nstore,1.0e-6,&ierror,TRUE); /*solve normal equations*/
if( ierror!=0 ) {
WriteLine( "Warning! singular matrix detected" );
}
DisposPtr( a );
if (strcmp(command.cmdWord[1],"type")==0) {
WriteLine("constant term");
RToS( vec[0], str );
WriteLine( str );
WriteLine("coefficients of the indepencent columns");
for( i=1; i<=nInd; i++ ) {
IToS( indList[i], str );
WritePhrase( str );
WritePhrase( " " );
RToS( vec[i], str );
WriteLine( str );
} /*end for i*/
} /*end if*/
else if( (strcmp(command.cmdWord[1],"keep")==0) ||
(strcmp(command.cmdWord[1],"remove")==0) ) {
if(strcmp(command.cmdWord[1],"remove")==0) {
flag=TRUE;
}
else {
flag=FALSE;
}
SToI( command.cmdWord[4], &zCol );
for( i=1; i<=table.header.rows; i++ ) {
z=vec[0];
for( j=1; j<=nInd; j++ ) {
GetTable( i, indList[j], &t );
z+=vec[j]*t;
} /*end for j*/
if (flag) {
GetTable( i, yCol, &y );
z = y-z;
} /*end if*/
SetTable( i, zCol, z, FALSE );
} /*end for i*/
} /*end if*/
/*save coefficients, etc*/
nCoeffs=nstore;
for( i=0; i<=nstore; i++ ) coeffs[i]=vec[i];
IToS( counts, str );
if( !SetVar( "counts", str ) ) {
ErrMsg("couldnt set variable");
}
}
noise()
{
float a, d, r;
double xnse();
int xCol, i;
SToR( command.cmdWord[1], &a, FALSE );
SToR( command.cmdWord[2], &d, FALSE );
if( d<=0.0 ) ErrMsg("std dev cant be non-positive");
SToI( command.cmdWord[3], &xCol );
for( i=1; i<=table.header.rows; i++ ) {
r = (float) xnse(a,d);
SetTable( i, xCol, r, FALSE );
}
}
double xnse(a,d)
float a, d;
/* returns a random number in a sequence with mean a and standard deviation d */
{
double sum, t, ss;
int i, n=10;
sum = 0.0;
t = sqrt( (double) (12.0*d*d/n) )/65536.0;
for( i=0; i<n; i++ ) {
sum += ran();
}
return( (sum*t + (double)a) );
}
polyfit()
{
int order, i, j, k, xCol, yCol, zCol, counts, ierror, flag;
float a[7][7], vec[7], xn[14], x, y, z, t;
char str[40];
SToI( command.cmdWord[1], &order );
if( (order<1) || (order>6) ) {
ErrMsg("order must be in range 1-6");
}
if( (strcmp(command.cmdWord[2],"type")!=0) &&
(strcmp(command.cmdWord[2],"keep")!=0) &&
(strcmp(command.cmdWord[2],"remove")!=0) &&
(strcmp(command.cmdWord[2],"compute")!=0) ) {
ErrMsg(badModifier);
}
SToI( command.cmdWord[3], &xCol );
SToI( command.cmdWord[4], &yCol );
if( (GoodCol(xCol)!=0) || (GoodCol(yCol)!=0) ) {
ErrMsg( "bad input column");
}
for( j=0; j<=order; j++ ) { /*zero matrix and vector*/
vec[j] = 0.0;
for( k=0; k<=order; k++ ) {
a[j][k] = 0.0;
} /*end for k*/
} /*end for k*/
counts=0;
i=1;
while( NextNotNaN( i, xCol, yCol, &i ) ) {
counts++;
GetTable( i, xCol, &x );
GetTable( i, yCol, &y );
xn[0]=1.0; /*compute powers of x*/
for( j=1; j<=(2*order); j++ ) {
xn[j] = x * xn[j-1];
} /*end for j*/
for( j=0; j<=order; j++ ) { /*zero matrix and vector*/
vec[j] += y*xn[j];
for( k=0; k<=order; k++ ) {
a[j][k] += xn[k+j];
} /*end for k*/
} /*end for k*/
i++;
} /*end while*/
gauss(a,vec,(order+1),7,1.0e-6,&ierror,TRUE); /*solve normal equations*/
if( ierror!=0 ) {
WriteLine( "Warning! singular matrix detected" );
}
if (strcmp(command.cmdWord[2],"type")==0) {
WriteLine("coefficients of x to the n, starting with n=0");
for( i=0; i<=order; i++ ) {
RToS( vec[i], str );
WriteLine( str );
} /*end for i*/
} /*end if*/
else if( (strcmp(command.cmdWord[2],"keep")==0) ||
(strcmp(command.cmdWord[2],"remove")==0) ) {
if(strcmp(command.cmdWord[2],"remove")==0) {
flag=TRUE;
}
else {
flag=FALSE;
}
SToI( command.cmdWord[5], &zCol );
for( i=1; i<=table.header.rows; i++ ) {
GetTable( i, xCol, &x );
xn[0]=1.0;
z=vec[0];
for( j=1; j<=order; j++ ) {
xn[j]=x*xn[j-1];
z+=xn[j]*vec[j];
} /*end for j*/
if (flag) {
GetTable( i, yCol, &y );
z = y-z;
} /*end if*/
SetTable( i, zCol, z, FALSE );
} /*end for i*/
} /*end if*/
/*save coefficients, etc*/
nCoeffs=order;
for( i=0; i<=order; i++ ) coeffs[i]=vec[i];
IToS( counts, str );
if( !SetVar( "counts", str ) ) {
ErrMsg("couldnt set variable");
}
}
gauss(a,vec,n,nstore,test,ierror,itriag)
float *a, vec[], test;
int n, nstore, *ierror, itriag;
{
/*subroutine gauss, by william menke, july 1978 (modified feb 1983, nov 85) */
/* a subroutine to solve a system of n linear equations in n unknowns, where n doesn't exceed 32 */
/*gaussian reduction with partial pivoting is used */
/* a (sent, destroyed) n by n matrix */
/* vec (sent, overwritten) n vector, replaced with solution */
/* nstore (sent) dimension of a */
/* test (sent) small pos no for div by zero check */
/* ierror (returned) error code. zero on no error */
/* itriag (sent) matrix triangularized only on TRUE */
/* useful when solving multiple */
/* systems with same a */
static int isub[32], l1;
int line[32], iet, ieb, i, j, k, l, j2;
float big, testa, b, sum;
iet=0; /* initial error flags, one for triagularization*/
ieb=0; /* one for backsolving */
/* triangularize the matrix a, replacing the zero elements of the triangularized matrix */
/* with the coefficients needed to transform the vector vec */
if (itriag) { /* triangularize matrix */
for( j=0; j<n; j++ ) { /*line is an array of flags*/
line[j]=0; /* elements of a are not moved during pivoting. line=0 flags unused lines */
} /*end for j*/
for( j=0; j<n-1; j++ ) { /* triangularize matrix by partial pivoting */
big = 0.0; /* find biggest element in j-th column of unused portion of matrix*/
for( l1=0; l1<n; l1++ ) {
if( line[l1]==0 ) {
testa=(float) fabs( (double) (*(a+l1*nstore+j)) );
if (testa>big) {
i=l1;
big=testa;
} /*end if*/
} /*end if*/
} /*end for l1*/
if( big<=test) { /* test for div by 0 */
iet=1;
} /*end if*/
line[i]=1; /* selected unused line becomes used line */
isub[j]=i; /* isub points to j-th row of triang. matrix */
sum=1.0/(*(a+i*nstore+j)); /* reduce matrix towards triangle */
for( k=0; k<n; k++ ) {
if( line[k]==0 ) {
b=(*(a+k*nstore+j))*sum;
for( l=j+1; l<n; l++ ) {
*(a+k*nstore+l)=(*(a+k*nstore+l))-b*(*(a+i*nstore+l));
} /*end for l*/
*(a+k*nstore+j)=b;
} /*end if*/
} /*end for k*/
} /*end for j*/
for( j=0; j<n; j++ ) { /*find last unused row and set its pointer*/
/* this row contians the apex of the triangle*/
if( line[j]==0) {
l1=j; /*apex of triangle*/
isub[n-1]=j;
break;
} /*end if*/
} /*end for j*/
} /*end if itriag true*/
/*start backsolving*/
for( i=0; i<n; i++ ) { /* invert pointers. line(i) now gives row no in triang matrix */
/* of i-th row of actual matrix */
line[isub[i]] = i;
} /*end for i*/
for( j=0; j<n-1; j++) { /* transform the vector to match triang. matrix*/
b=vec[isub[j]];
for( k=0; k<n; k++ ) {
if (line[k]>j) { /* skip elements outside of triangle*/
vec[k]=vec[k]-(*(a+k*nstore+j))*b;
} /*end if*/
} /*end for k*/
} /*end for j*/
b = *(a+l1*nstore+(n-1)); /*apex of triangle*/
if( ((float)fabs( (double) b))<=test) { /*check for div by zero in backsolving*/
ieb=2;
} /*end if*/
vec[isub[n-1]]=vec[isub[n-1]]/b;
for( j=n-2; j>=0; j-- ) { /* backsolve rest of triangle*/
sum=vec[isub[j]];
for( j2=j+1; j2<n; j2++ ) {
sum = sum - vec[isub[j2]] * (*(a+isub[j]*nstore+j2));
} /*end for j2*/
b = *(a+isub[j]*nstore+j);
if( ((float)fabs((double)b))<=test) { /* test for div by 0 in backsolving */
ieb=2;
} /*end if*/
vec[isub[j]]=sum/b; /*solution returned in vec*/
} /*end for j*/
/*put the solution vector into the proper order*/
for( i=0; i<n; i++ ) { /* reorder solution */
for( k=i; k<n; k++ ) { /* search for i-th solution element */
if( line[k]==i ) {
j=k;
break;
} /*end if*/
} /*end for k*/
b = vec[j]; /* swap solution and pointer elements*/
vec[j] = vec[i];
vec[i] = b;
line[j] = line[i];
} /*end for i*/
*ierror = iet + ieb; /* set final error flag*/
}